/**
 * @EventTypeMetainfoUtils.java  COPYRIGHT xiaojian
 * 
 * Created on 2016年7月18日 下午3:04:19
 */
package xj.toolkit.ebus.meta;

import java.io.IOException;
import java.util.Collection;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Lists;

import xj.toolkit.ebus.annotation.Eventable;
import xj.toolkit.ebus.annotation.Events;
import xj.toolkit.util.PackageUtils;
import xj.toolkit.util.StringUtils;

/**
 * @author <a href="mailto:cxj2000@gmail.com">xiaojian.cao</a>
 *
 */
public class EventTypeMetainfoUtils {
	
	private static final Logger logger = LoggerFactory.getLogger(EventTypeMetainfoUtils.class);
	
	static public EventTypeMetainfo createEventTypeMetainfoByClasses(Collection<Class<?>> clazzes) {
		EventTypeMetainfo eventTypeMetaInfo = new EventTypeMetainfo();

		for (Class<?> cls : clazzes) {
			Events events = cls.getAnnotation(Events.class);
			if (events != null) {
				List<String> eventLst = Lists.newArrayList(events.value());
				if (!eventLst.isEmpty()) {
					eventTypeMetaInfo.add(cls, eventLst);
				}
			}

			Eventable eventable = cls.getAnnotation(Eventable.class);
			if (eventable != null) {
				eventTypeMetaInfo.add(cls, Lists.newArrayList("event." + cls.getName()));
			}
		}

		return eventTypeMetaInfo;
	}

	static public EventTypeMetainfo createEventTypeMetaInfoByPackages(Collection<String> packages) {
		EventTypeMetainfo eventTypeMetaInfo = new EventTypeMetainfo();

		if (packages == null || packages.size() == 0) {
			return eventTypeMetaInfo;
		}

		for (String pkgName : packages) {
			try {
				String[] clsNames = PackageUtils.findClassesInPackage(pkgName, null, null);
				ClassLoader cl = Thread.currentThread().getContextClassLoader();
				for (String clsName : clsNames) {
					if (logger.isDebugEnabled()) {
						logger.debug("using ClassLoader {} to load Class {}", cl, clsName);
					}
					Class<?> cls = null;
					try {
						cls = cl.loadClass(clsName);
					} catch (ClassNotFoundException e) {
						logger.error("createEventTypeMetaInfoByPackages: ", e);
						continue;
					}

					if (cls == null) {
						continue;
					}

					Events events = cls.getAnnotation(Events.class);
					if (events != null) {
						List<String> eventLst = StringUtils.stringToList(events.value());
						if (!eventLst.isEmpty()) {
							eventTypeMetaInfo.add(cls, eventLst);
						}
					}

					Eventable eventable = cls.getAnnotation(Eventable.class);
					if (eventable != null) {
						eventTypeMetaInfo.add(cls, Lists.newArrayList("event." + cls.getName()));
					}
				}
			} catch (IOException e) {
				logger.error("createTypeMetainfo: ", e);
			}
		}

		return eventTypeMetaInfo;

	}
}
